package com.ab.scale;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.aibao.serialportlibrary.Device;
import com.aibao.serialportlibrary.SerialPortFinder;
import com.aibao.serialportlibrary.SerialPortManager;
import com.aibao.serialportlibrary.listener.OnOpenSerialPortListener;
import com.aibao.serialportlibrary.listener.OnSerialPortDataListener;

import java.io.File;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private final static String POWER_COMMAND = "3C 50 57 3E 09";
    private final static String PEEL_COMMAND = "3C 54 4B 3E 09";
    private final static String RETURN_0_COMMAND = "3C 5A 4B 3E 09";
    private final String DEFAULT_DEVICE_NAME = "ttyS9";
    private SerialPortManager serialPortManager;
    private TextView tvConnect, tvReceive;
    private boolean isOpen = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvConnect = findViewById(R.id.tv_connect);
        tvConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOpen) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            disconnect();
                        }
                    }).start();
                } else {
                    Toast.makeText(MainActivity.this, "start connect", Toast.LENGTH_SHORT).show();
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            connect();
                        }
                    }).start();
                }
            }
        });
        findViewById(R.id.tv_power).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (serialPortManager != null && isOpen) {
                    Toast.makeText(MainActivity.this, "Power", Toast.LENGTH_SHORT).show();
                    sendCommand(POWER_COMMAND);
                } else {
                    Toast.makeText(MainActivity.this, "Serial port not open", Toast.LENGTH_SHORT).show();
                }
            }
        });
        findViewById(R.id.tv_peel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (serialPortManager != null && isOpen) {
                    Toast.makeText(MainActivity.this, "Peel", Toast.LENGTH_SHORT).show();
                    sendCommand(PEEL_COMMAND);
                } else {
                    Toast.makeText(MainActivity.this, "Serial port not open", Toast.LENGTH_SHORT).show();
                }
            }
        });
        findViewById(R.id.tv_return_0).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (serialPortManager != null && isOpen) {
                    Toast.makeText(MainActivity.this, "Return 0", Toast.LENGTH_SHORT).show();
                    sendCommand(RETURN_0_COMMAND);
                } else {
                    Toast.makeText(MainActivity.this, "Serial port not open", Toast.LENGTH_SHORT).show();
                }
            }
        });
        tvReceive = findViewById(R.id.tv_receive);
    }

    private void connect() {
        Device connectDevice = null;
        //Get the list of local serial ports
        List<Device> devices = new SerialPortFinder().getDevices();
        for (int i = 0; i < devices.size(); i++) {
            //In actual use, the serial port name is not fixed, you need to display the serial port list to select and try to open.
            if (DEFAULT_DEVICE_NAME.equals(devices.get(i).getName())) {
                connectDevice = devices.get(i);
                break;
            }
        }
        if (connectDevice == null) {
            Log.d("scaleConnect", "connectDevice is null!");
            return;
        }
        serialPortManager = new SerialPortManager();
        //Set callback
        serialPortManager.setOnOpenSerialPortListener(new OnOpenSerialPortListener() {
            @Override
            public void onSuccess(File device) {
                Log.d("scaleConnect", "Serial port successfully opened");
            }

            @Override
            public void onFail(File device, OnOpenSerialPortListener.Status status) {
                Log.d("scaleConnect", "Failed to open the serial port");
            }
        }).setOnSerialPortDataListener(new OnSerialPortDataListener() {
            @Override
            public void onDataReceived(String value) {
                Log.d("scaleConnect", "onDataReceived value=" + value);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvReceive.setText("receive : " + value);
                    }
                });
            }

            @Override
            public void onDataSent(byte[] bytes) {

            }
        });
        //Open the serial port
        //The baud rate of the scale is generally fixed at 9600
        isOpen = serialPortManager.openSerialPort(connectDevice, 9600);
        Log.d("scaleConnect", "openSerialPort result = " + isOpen);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (isOpen) {
                    Toast.makeText(MainActivity.this, "connect successfully", Toast.LENGTH_SHORT).show();
                    tvConnect.setText("disconnect");
                }
            }
        });
    }

    private void disconnect() {
        if (serialPortManager != null) {
            serialPortManager.closeSerialPort();
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "disconnect", Toast.LENGTH_SHORT).show();
                isOpen = false;
                tvConnect.setText("connect");
                tvReceive.setText("receive : ");
            }
        });
    }

    private void sendCommand(String command) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String s = command;
                s = s.replace(" ", "");
                byte[] bytes = hexToByteArr(s);
                serialPortManager.sendBytes(bytes);
            }
        }).start();
    }

    public static byte[] hexToByteArr(String inHex) {
        byte[] result;
        int hexlen = inHex.length();
        if (isOdd(hexlen) == 1) {
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = HexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }

    public static int isOdd(int num) {
        return num & 1;
    }

    public static byte HexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

}